跳到主要内容

行为型模式-职责链模式

参考资料 责任链模式 参考资料 状态模式和责任链模式的区别

什么是职责链模式

职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

它适合用来做拦截器,注意它和装饰器模式的区别,装饰器模式是对被装饰者行为进行补充增强

solution1-zh.png

不一定是链式结构,也可以从对象树中抽取出链来 solution2-zh.png

职责链的结构

职责链模式主要包含以下角色。

1、抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

2、具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

3、客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

职责链模式(Chain of Responsibility)结构图

classDiagram Client --> Handler Handler <|.. BaseHandler BaseHandler <|-- ConcreteHandlers BaseHandler o--> Handler Handler: <<interface>> Handler: +setNext(Handler) Handler: +handle(request) BaseHandler: -Handler next BaseHandler: +setNext(Handler) BaseHandler: +handle(request) ConcreteHandlers: ... ConcreteHandlers: +handle(request)

职责链和状态模式的区别

职责链模式有点像上面的状态模式,都需要指向下一个状态。这两种模式还是有点区别的,状态模式把各种状态转移逻辑分布到 State 的子类之间,来减少相互间的依赖(If ,else-if,else-if…… 转到 State 内部)。但是它有一个问题,就是指向的状态在某处断了,那整个事件都无法再传递下去了。(就是状态机内部维护了一个当前状态)

而职责链模式则是为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。(可以动态地增加或删减处理请求的链结构

  • 责任链模式注重请求的传递

  • 状态模式注重对象状态的转换

代码实现

Handler 类定义一个处理请求的接口

public abstract class Handler {
protected Handler successor;

public void setSuccessor(Handler successor) {
this.successor = successor;
}

public abstract void handleRequest(int request);
}

ConcreteHandlers 具体的处理者类,如果可处理该请求就处理,否则就将该请求转发给它的后继者

public class ConcreteHandlersA extends Handler {

@Override
public void handleRequest(int request) {
if(request >=0 && request < 10) {
System.out.println("当前 request 是:" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}

public class ConcreteHandlersB extends Handler {

@Override
public void handleRequest(int request) {
if(request >=10 && request < 20) {
System.out.println("当前 request 是:" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}

public class ConcreteHandlersC extends Handler {

@Override
public void handleRequest(int request) {
if(request >=20 && request < 30) {
System.out.println("当前 request 是:" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}

客户端代码

// 可以动态地增加或删减处理请求的链结构
Handler h1 = new ConcreteHandlersA();
Handler h2 = new ConcreteHandlersB();
Handler h3 = new ConcreteHandlersC();

h1.setSuccessor(h2);
h2.setSuccessor(h3);

int[] requests = {2,5,24,22};
for (int request : requests) {
h1.handleRequest(request)
}